package com.controller;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.base.Myprops;
import com.model.auto.*;
import com.model.auto.vo.AutoCreateVo;
import com.model.auto.vo.UptStuSchemeVo;
import com.service.*;
import com.util.*;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.math.BigDecimal;
import java.nio.charset.StandardCharsets;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 新高考方案设计相关
 *
 * @author astupidcoder
 * @since 2022-09-14
 */
@RestController
@RequestMapping("/stuSchemeV2")
@Slf4j
public class StuSchemeV2Controller {
    @Autowired
    private IStuSchemeV2Service stuSchemeService;
    @Autowired
    private IStudentService studentService;
    @Autowired
    private ISchoolV2Service schoolService;
    @Autowired
    private IMajorV2Service majorV2Service;
    @Autowired
    private Myprops myprops;
    @Autowired
    private ISchoolLabelService schoolLabelService;
    @Autowired
    private IMajorV2Service majorService;
    @Autowired
    private ISchoolInfoV2Service schoolInfoV2Service;

    private Logger logger = LoggerFactory.getLogger(StuSchemeV2Controller.class);


    //查询方案
    @PostMapping("/getProgramme")
    public R getProgramme(String stuId) {
        List<StuSchemeV2> list = stuSchemeService.getProgrammes(stuId);
        String[] regulation = {"本科提前批单设", "本科提前批平行", "高职专科批提前", "本科普通批单设", "本科普通批平行", "高职专科批普通"};
        final List<String> regulationOrder = Arrays.asList(regulation);
        Collections.sort(list, new Comparator<StuSchemeV2>() {
            @Override
            public int compare(StuSchemeV2 o1, StuSchemeV2 o2) {
                String websiteName1 = (String) o1.getBatch();
                String websiteName2 = (String) o2.getBatch();
                int io1 = regulationOrder.indexOf(websiteName1);
                int io2 = regulationOrder.indexOf(websiteName2);
                return (io1 == -1 || io2 == -1) ? (io2 - io1) : (io1 - io2);
            }
        });
        return R.ok(list);
    }

    @PostMapping("/getScheme")
    public R getScheme(String stuId, Integer programmeId, String batch, Integer precedence, Integer majorType) {
//        System.out.println("--------=======" + stuId);
//        System.out.println("--------方案id" + programmeId);
//        List<StuSchemeV2> list = stuSchemeService.list(new LambdaQueryWrapper<StuSchemeV2>()
//                .eq(!StringUtil.isEmpty(stuId), StuSchemeV2::getStuId, stuId)
//                .eq(programmeId != null, StuSchemeV2::getProgrammeId, programmeId)
//                .eq(batch != null, StuSchemeV2::getBatch, batch)
//        );

        List<StuSchemeV2> list = stuSchemeService.getStuScheme(stuId, programmeId, batch, majorType);
        //兼容手机端不传precedence参数
        if (Objects.nonNull(list) && list.size() > 0 && Objects.nonNull(list.get(0).getPrecedence())) {
            precedence = list.get(0).getPrecedence();
        }
        if (Objects.isNull(precedence)) {
            Student student = studentService.getById(stuId);
            if (Objects.nonNull(student) && !StringUtil.isEmpty(student.getPrecedence()) && StringUtil.isNumeric(student.getPrecedence())) {
                precedence = Integer.valueOf(student.getPrecedence());
            }
        }

        for (StuSchemeV2 stuScheme : list) {
            if ("0".equals(stuScheme.getSchemeChange())) {
                stuScheme.setSchemeChangeFlag(true);
            } else {
                stuScheme.setSchemeChangeFlag(false);
            }
            SchoolV2 schoolV2 = schoolService.queryByParams(stuScheme.getMajorType(), stuScheme.getBatch(), stuScheme.getSchoolCode(), stuScheme.getGroupCode());
            if (Objects.nonNull(schoolV2)) {
                stuScheme.setSchoolInfo(schoolInfoV2Service.selectBySchoolName(schoolV2.getSchoolName()));
                stuScheme.setGroupProposedwc(schoolV2.getGroupProposedwc());
                stuScheme.setGroupProposedScore(schoolV2.getGroupProposedScore());
            }
            //获取报考专业
            if (StringUtils.hasText(stuScheme.getMajorList())) {
                List<JSONObject> majorList = JSONArray.parseArray(stuScheme.getMajorList(), JSONObject.class);
                for (JSONObject major : majorList) {
                    MajorV2 major1 = majorV2Service.selectByParams(stuScheme.getSchoolCode(), stuScheme.getGroupCode(), major.getString("majorCode"));
                    if (Objects.nonNull(major1)) {
                        if (StringUtils.hasText(major1.getExamLimit())) {
                            major.put("examLimit", major1.getExamLimit());
                        } else {
                            major.put("examLimit", "");
                        }
                        if (StringUtils.hasText(major1.getMajorDesc())) {
                            major.put("majorDesc", major1.getMajorDesc());
                        } else {
                            major.put("majorDesc", "");
                        }
                        if (StringUtils.hasText(major1.getMsg2015())) {
                            major.put("msg2015", major1.getMsg2015());
                        } else {
                            major.put("msg2015", "");
                        }
                        if (StringUtils.hasText(major1.getToudang2015())) {
                            major.put("toudang2015", major1.getToudang2015());
                        } else {
                            major.put("toudang2015", "");
                        }
                        if (StringUtils.hasText(major1.getShiftLine2015())) {
                            major.put("shiftLine2015", major1.getShiftLine2015());
                        } else {
                            major.put("shiftLine2015", "");
                        }
                        if (StringUtils.hasText(major1.getRanking2015())) {
                            major.put("ranking2015", major1.getRanking2015());
                        } else {
                            major.put("ranking2015", "");
                        }
                        if (StringUtils.hasText(major1.getMinShiftLine2015())) {
                            major.put("minShiftLine2015", major1.getMinShiftLine2015());
                        } else {
                            major.put("minShiftLine2015", "");
                        }
                        if (StringUtils.hasText(major1.getMinRanking2015())) {
                            major.put("minRanking2015", major1.getMinRanking2015());
                        } else {
                            major.put("minRanking2015", "");
                        }
                        if (StringUtils.hasText(major1.getMsg2016())) {
                            major.put("msg2016", major1.getMsg2016());
                        } else {
                            major.put("msg2016", "");
                        }
                        if (StringUtils.hasText(major1.getToudang2016())) {
                            major.put("toudang2016", major1.getToudang2016());
                        } else {
                            major.put("toudang2016", "");
                        }
                        if (StringUtils.hasText(major1.getShiftLine2016())) {
                            major.put("shiftLine2016", major1.getShiftLine2016());
                        } else {
                            major.put("shiftLine2016", "");
                        }
                        if (StringUtils.hasText(major1.getRanking2016())) {
                            major.put("ranking2016", major1.getRanking2016());
                        } else {
                            major.put("ranking2016", "");
                        }
                        if (StringUtils.hasText(major1.getMinShiftLine2016())) {
                            major.put("minShiftLine2016", major1.getMinShiftLine2016());
                        } else {
                            major.put("minShiftLine2016", "");
                        }
                        if (StringUtils.hasText(major1.getMinRanking2016())) {
                            major.put("minRanking2016", major1.getMinRanking2016());
                        } else {
                            major.put("minRanking2016", "");
                        }
                        if (StringUtils.hasText(major1.getMsg2017())) {
                            major.put("msg2017", major1.getMsg2017());
                        } else {
                            major.put("msg2017", "");
                        }
                        if (StringUtils.hasText(major1.getToudang2017())) {
                            major.put("toudang2017", major1.getToudang2017());
                        } else {
                            major.put("toudang2017", "");
                        }
                        if (StringUtils.hasText(major1.getShiftLine2017())) {
                            major.put("shiftLine2017", major1.getShiftLine2017());
                        } else {
                            major.put("shiftLine2017", "");
                        }
                        if (StringUtils.hasText(major1.getRanking2017())) {
                            major.put("ranking2017", major1.getRanking2017());
                        } else {
                            major.put("ranking2017", "");
                        }
                        if (StringUtils.hasText(major1.getMinShiftLine2017())) {
                            major.put("minShiftLine2017", major1.getMinShiftLine2017());
                        } else {
                            major.put("minShiftLine2017", "");
                        }
                        if (StringUtils.hasText(major1.getMinRanking2017())) {
                            major.put("minRanking2017", major1.getMinRanking2017());
                        } else {
                            major.put("minRanking2017", "");
                        }
                        if (StringUtils.hasText(major1.getLevel())) {
                            major.put("level", major1.getLevel());
                        } else {
                            major.put("level", "");
                        }
                        major.put("plan2017", major1.getPlan2017());
                        //获取专业录取概率
                        getMajorProbability(major1, precedence);
                        major.put("probability", major1.getProbability());
                        major.put("probabilityName", major1.getProbability());
                    }
                }
                stuScheme.setMajorList(JSONObject.toJSONString(majorList));
            }
            if(StringUtils.hasText(stuScheme.getSubject())){
                stuScheme.setSubject(schoolV2.getSubject().replaceAll(",","+"));
            }
            //获取院校录取概率
            getSchoolProbability(stuScheme, precedence);
        }
        System.out.println("===========结果" + list);
        int chongNum = 0;
        int wenNum = 0;
        int baoNum = 0;
        int allNum = 0;
        if(!CollectionUtils.isEmpty(list)){
            try{
                chongNum = list.stream().filter(data->"冲".equals(data.getProbabilityName())).collect(Collectors.toList()).size();
                wenNum = list.stream().filter(data->"稳".equals(data.getProbabilityName())).collect(Collectors.toList()).size();
                baoNum = list.stream().filter(data->"保".equals(data.getProbabilityName())).collect(Collectors.toList()).size();
                allNum = list.size();
            }catch (Exception e){
                log.error("计算冲稳保数量异常，异常信息=", e);
            }
        }
        return R.ok(list).put("chongNum", chongNum)
                .put("wenNum", wenNum).put("baoNum", baoNum).put("allNum", allNum);
    }

    /**
     * 获取院校录取概率
     *
     * @param stuSchemeV2
     * @param precedence
     */
    private void getSchoolProbability(StuSchemeV2 stuSchemeV2, Integer precedence) {
        if (Objects.nonNull(precedence) && precedence > 0) {
            Map<String, String> probabilityMap = ProbabilityUtils.getProbability(stuSchemeV2.getMajorType(), stuSchemeV2.getGroupProposedwc(), precedence);
            if (StringUtils.hasText(probabilityMap.get("probability"))) {
                stuSchemeV2.setProbability(probabilityMap.get("probability"));
                stuSchemeV2.setProbabilityName(probabilityMap.get("probabilityName"));
                BigDecimal probabilityNum = new BigDecimal(probabilityMap.get("probability").replace("%", ""));
                stuSchemeV2.setProbabilityNum(probabilityNum);
            }
        }
    }

    /**
     * 获取院校录取概率
     *
     * @param schoolV2
     * @param precedence
     */
    private void getSchoolProbability(SchoolV2 schoolV2, Integer precedence) {
        if (Objects.nonNull(precedence) && precedence > 0) {
            Map<String, String> probabilityMap = ProbabilityUtils.getProbability(schoolV2.getType(), schoolV2.getGroupProposedwc(), precedence);
            if (StringUtils.hasText(probabilityMap.get("probability"))) {
                schoolV2.setProbability(probabilityMap.get("probability"));
                try {
                    BigDecimal probabilityNum = new BigDecimal(probabilityMap.get("probability").replace("%", ""));
                    schoolV2.setProbabilityNum(probabilityNum);
                } catch (Exception e) {
                    logger.error("获取院校录取概率异常，异常信息：", e);
                    schoolV2.setProbabilityNum(new BigDecimal(0));
                }
                schoolV2.setProbabilityName(probabilityMap.get("probabilityName"));
            }
        }
    }

    /**
     * 获取专业录取概率
     *
     * @param majorV2
     * @param precedence
     */
    private void getMajorProbability(MajorV2 majorV2, Integer precedence) {
        if (Objects.nonNull(precedence) && precedence > 0) {
            Map<String, String> probabilityMap = ProbabilityUtils.getProbability(majorV2.getType(), majorV2.getMajorWeici(), precedence);
            if (StringUtils.hasText(probabilityMap.get("probability"))) {
                majorV2.setProbability(probabilityMap.get("probability"));
                try {
                    BigDecimal probabilityNum = new BigDecimal(probabilityMap.get("probability").replace("%", ""));
                    majorV2.setProbabilityNum(probabilityNum);
                } catch (Exception e) {
                    logger.error("获取专业录取概率异常，异常信息：", e);
                    majorV2.setProbabilityNum(new BigDecimal(0));
                }
                majorV2.setProbabilityName(probabilityMap.get("probabilityName"));
            }
        }
    }

    @GetMapping("/getSchemePdf")
    public void getSchemePdf(String stuId, Integer programmeId, String batch, HttpServletResponse response) {
        List<StuSchemeV2> list = stuSchemeService.list(new LambdaQueryWrapper<StuSchemeV2>()
                .eq(!StringUtil.isEmpty(stuId), StuSchemeV2::getStuId, stuId)
                .eq(programmeId != null, StuSchemeV2::getProgrammeId, programmeId)
                .eq(batch != null, StuSchemeV2::getBatch, batch)
        );

        fillSchemeMsg(list);

//        //按照序列名称排序
//        Collections.sort(list, new Comparator<StuScheme>() {
//            @Override
//            public int compare(StuScheme scheme1, StuScheme scheme2) {
//                if(ObjectUtils.isEmpty(scheme1.getSchemeName()) || ObjectUtils.isEmpty(scheme2.getSchemeName())){
//                    return 1;
//                }
//                if("备选".equals(scheme1.getSchemeName())){
//                    return 1;
//                }
//                return scheme1.getSchemeName().compareTo(scheme2.getSchemeName());
//            }
//        });

        List<List<StuSchemeV2>> scheme = new ArrayList<>();
        scheme.add(list);

        Student student = studentService.getById(stuId);
        String filePath = myprops.getSavePath() + File.separator + DateUtils.format(new Date(), "yyyyMMdd");
        File folder = new File(filePath);
        if (!folder.exists()) {
            folder.mkdirs();
            log.debug("创建文件夹{}成功", filePath);
        }

        String fileName = student.getName() + list.get(0).getProgrammeName() + ".pdf";
        PdfUtil.createPdfV2(filePath + File.separator + fileName, scheme, student, false);


        String downloadFileName = new String(fileName.getBytes(StandardCharsets.UTF_8), StandardCharsets.ISO_8859_1);

        response.reset();
        response.setCharacterEncoding("UTF-8");
        response.setContentType("multipart/form-data");
        response.addHeader("Content-Disposition", "attachment; filename=\"" + downloadFileName + "\"");

        InputStream input = null;
        OutputStream output = null;
        try {
            File file = new File(filePath + File.separator + fileName);
            input = new FileInputStream(file);
            output = response.getOutputStream();
            byte[] buff = new byte[1024];
            int index;
            while ((index = input.read(buff)) != -1) {
                output.write(buff, 0, index);
                output.flush();
            }
        } catch (Exception e) {
            log.error("download template error", e);
        } finally {
            if (input != null) {
                try {
                    input.close();
                } catch (IOException e) {
                    log.error("关闭input异常：", e);
                }
            }
            if (output != null) {
                try {
                    output.close();
                } catch (IOException e) {
                    log.error("关闭output异常：", e);
                }
            }
        }
    }

    @GetMapping("/getMobileSchemePdf")
    public R getMobileSchemePdf(String stuId, Integer programmeId, String batch, HttpServletResponse response) {
        List<StuSchemeV2> list = stuSchemeService.list(new LambdaQueryWrapper<StuSchemeV2>()
                .eq(!StringUtil.isEmpty(stuId), StuSchemeV2::getStuId, stuId)
                .eq(programmeId != null, StuSchemeV2::getProgrammeId, programmeId)
                .eq(batch != null, StuSchemeV2::getBatch, batch)
        );

//        //按照序列名称排序
//        Collections.sort(list, new Comparator<StuScheme>() {
//            @Override
//            public int compare(StuScheme scheme1, StuScheme scheme2) {
//                if(ObjectUtils.isEmpty(scheme1.getSchemeName()) || ObjectUtils.isEmpty(scheme2.getSchemeName())){
//                    return 1;
//                }
//                if("备选".equals(scheme1.getSchemeName())){
//                    return 1;
//                }
//                return scheme1.getSchemeName().compareTo(scheme2.getSchemeName());
//            }
//        });

        List<List<StuSchemeV2>> scheme = new ArrayList<>();
        scheme.add(list);

        Student student = studentService.getById(stuId);
        String filePath = myprops.getSavePath() + File.separator + DateUtils.format(new Date(), "yyyyMMdd");
        File folder = new File(filePath);
        if (!folder.exists()) {
            folder.mkdirs();
            log.debug("创建文件夹{}成功", filePath);
        }

        String fileName = student.getName() + list.get(0).getProgrammeName() + ".pdf";

        String savePdfPath = filePath + File.separator + fileName;
        PdfUtil.createPdfV2(savePdfPath, scheme, student, false);

        String data = "https://img.51mydoor.com"+savePdfPath.replace(myprops.getSavePath(),"");
        return R.ok("下载成功").put("data", data);
    }

    //删除志愿
    @PostMapping("/deleteScheme")
    public R deleteScheme(Integer Id) {
        System.out.println("=========id是" + Id);
        return R.ok(stuSchemeService.removeById(Id));
    }

    //删除方案
    @GetMapping("/deleteProgramme")
    public R deleteNewStuScheme(Integer programmeId, Integer stuId, String batch) {
        if (programmeId != null && stuId != null) {
            List<StuSchemeV2> list = stuSchemeService.list(new LambdaQueryWrapper<StuSchemeV2>()
                    .eq(StuSchemeV2::getStuId, stuId)
                    .eq(StuSchemeV2::getProgrammeId, programmeId)
                    .eq(StuSchemeV2::getBatch, batch)
            );
            if (!ObjectUtils.isEmpty(list)) {
                List<Object> idList = new ArrayList<>();
                if (list.size() > 0) {
                    list.forEach(i -> {
                        idList.add(i.getId());
                    });
                }
                stuSchemeService.removeBatchByIds(idList);
            }
            return R.ok();
        }
        return R.error();
    }

    //修改方案名称
    @PostMapping("/updateName")
    public R updateName(String name, Integer programmeId, String stuId) {
        stuSchemeService.update(new LambdaUpdateWrapper<StuSchemeV2>()
                .eq(programmeId != null, StuSchemeV2::getProgrammeId, programmeId)
                .eq(!StringUtil.isEmpty(stuId), StuSchemeV2::getStuId, stuId)
                .set(!StringUtil.isEmpty(name), StuSchemeV2::getProgrammeName, name)
        );
        return R.ok();
    }

    //修改方案信息
    @PostMapping("/updateProgramme")
    public R updateProgramme(@RequestBody UptStuSchemeVo uptStuSchemeVo) {
        boolean update = stuSchemeService.update(new LambdaUpdateWrapper<StuSchemeV2>()
                .eq(!StringUtil.isEmpty(uptStuSchemeVo.getStuId()), StuSchemeV2::getStuId, uptStuSchemeVo.getStuId())
                .eq(uptStuSchemeVo.getProgrammeId() != null, StuSchemeV2::getProgrammeId, uptStuSchemeVo.getProgrammeId())
                .set(!StringUtil.isEmpty(uptStuSchemeVo.getBatch()), StuSchemeV2::getBatch, uptStuSchemeVo.getBatch())
                .set(uptStuSchemeVo.getRanking() != null, StuSchemeV2::getRanking, uptStuSchemeVo.getRanking())
                .set(!StringUtil.isEmpty(uptStuSchemeVo.getFraction()), StuSchemeV2::getFraction, uptStuSchemeVo.getFraction())
                .set(StuSchemeV2::getMinfraction, uptStuSchemeVo.getMinfraction())
                .set(StuSchemeV2::getMaxfraction, uptStuSchemeVo.getMaxfraction())
                .set(!StringUtil.isEmpty(uptStuSchemeVo.getProgrammeName()), StuSchemeV2::getProgrammeName, uptStuSchemeVo.getProgrammeName())
                .set(StuSchemeV2::getMaxranking, uptStuSchemeVo.getMaxranking())
                .set(StuSchemeV2::getMinranking, uptStuSchemeVo.getMinranking())
        );
        if (update) {
            return R.ok();
        } else {
            return R.error("修改失败！");
        }
    }

    @PostMapping("/saveScheme")
    public R saveScheme(@RequestBody StuSchemeV2[] stuScheme) {
        log.info("保存专业请求参数={}", JSONObject.toJSONString(stuScheme));
        Integer maxProgrammeId = stuSchemeService.getObj(new QueryWrapper<StuSchemeV2>()
                .select("ifnull(max(programme_id),0) as maxNum")
                .eq("stu_id", stuScheme[0].getStuId())
                .eq("batch", stuScheme[0].getBatch())
                .eq("major_type", stuScheme[0].getMajorType())
                .orderByDesc("programme_id"), i -> Integer.valueOf(i.toString())
        );
        if(maxProgrammeId >= 99){
            return R.error("最多可创建99个方案");
        }
        //默认招生类别
        List<String> defaultRecruitType = new ArrayList<>();
        defaultRecruitType.add("普通志愿");
        defaultRecruitType.add("中外合办");
        List<StuSchemeV2> stuSchemes = Arrays.asList(stuScheme);

        for(StuSchemeV2 stuSchemeV2:stuSchemes){
            if(StringUtils.isEmpty(stuSchemeV2.getSubject1()) && StringUtils.hasText(stuSchemeV2.getStuId())){
                Student student = studentService.getById(stuSchemeV2.getStuId());
                stuSchemeV2.setSubject1(student.getSubject1());
                stuSchemeV2.setSubject2(student.getSubject2());
            }
        }

        Integer schemeType = getSchemeType(stuSchemes);

        if (stuScheme.length < 2 && StringUtil.isEmpty(stuSchemes.get(0).getSchoolCode())) {
            for (StuSchemeV2 scheme : stuScheme) {
                if (Objects.isNull(scheme.getSchemeType())) {
                    scheme.setSchemeType(schemeType);
                }
                if (scheme.getProgrammeId() == null) {

                    stuSchemes.forEach(i -> {
                        List<StuSchemeV2> schemes = stuSchemeService.list(new LambdaQueryWrapper<StuSchemeV2>()
                                .eq(scheme.getStuId() != null, StuSchemeV2::getStuId, scheme.getStuId())
                                .orderByDesc(StuSchemeV2::getNum).last("limit 1")
                        );
                        i.setProgrammeId(maxProgrammeId + 1);
                        if (schemes.size() > 0) {
                            i.setNum(schemes.get(0).getNum() + 1);
                        } else {
                            i.setNum(1);
                        }
                    });

                }
                if (StringUtil.isEmpty(scheme.getSchemeName())) {
                    Integer count = stuSchemeService.queryGroupByParam(scheme);
                    String majorType = "物理";
                    if (scheme.getMajorType() == 2 || scheme.getMajorType() == 4) {
                        majorType = "历史";
                    }
                    String name = majorType + scheme.getBatch() + (count + 1);
                    stuSchemes.forEach(stuSchemeV2 -> {
                        stuSchemeV2.setProgrammeName(name);
                        stuSchemeV2.setSchemeRecruitType(String.join(",", defaultRecruitType));
                        //判断专业是否有值
                        if (StringUtils.hasText(stuSchemeV2.getMajorList())) {
                            JSONArray majorList = JSONObject.parseArray(stuSchemeV2.getMajorList());
                            //先排序
                            majorList.sort((o1, o2) -> {
                                JSONObject jo1 = (JSONObject) o1;
                                JSONObject jo2 = (JSONObject) o2;
                                String sort1 = jo1.getString("sort");
                                String sort2 = jo2.getString("sort");
                                return sort1.compareTo(sort2);
                            });

                            for (int index = 0; index < majorList.size(); index++) {
                                JSONObject major = majorList.getJSONObject(index);
                                int majorSort = index + 1;
                                major.put("sort", "专业" + majorSort);
                                majorList.set(index, major);
                            }
                            stuSchemeV2.setMajorList(JSONObject.toJSONString(majorList));
                        }
                    });
                }
                long count = stuSchemeService.count(new LambdaQueryWrapper<StuSchemeV2>().
                        eq(StuSchemeV2::getProgrammeName, scheme.getProgrammeName())
                        .eq(StuSchemeV2::getStuId, scheme.getStuId())
                        .eq(StuSchemeV2::getBatch, scheme.getBatch())
                );
//                    System.out.println("他的数量" + count);
                if (count > 0) {
                    return R.error("该方案名称已存在！");
                } else {
                    boolean b = stuSchemeService.saveBatch(stuSchemes);
                    //更新序号
                    UpdateSort(stuSchemes.get(0));

                    HashMap<String, Object> object = new HashMap<>();
                    object.put("bol", b);
                    object.put("list", stuSchemes);
                    return R.ok(object);
                }
            }

        } else {
            int programmeid = maxProgrammeId + 1;
            if (stuSchemes.get(0).getProgrammeId() != null) {
                programmeid = stuSchemes.get(0).getProgrammeId();
            }
            String stuId = stuSchemes.get(0).getStuId();
            if (!StringUtil.isEmpty(stuId)) {
                stuSchemeService.remove(new LambdaQueryWrapper<StuSchemeV2>()
                        .eq(StuSchemeV2::getProgrammeId, programmeid)
                        .eq(StuSchemeV2::getStuId, stuId)
                        .eq(StuSchemeV2::getBatch, stuSchemes.get(0).getBatch())
                        .eq(StuSchemeV2::getMajorType, stuSchemes.get(0).getMajorType())
                );

                stuSchemes.removeIf(scheme -> StringUtil.isEmpty(scheme.getSchoolCode()));
                Integer sort = 1;
                for (StuSchemeV2 stuSchemeV2 : stuSchemes) {
                    if (Objects.isNull(stuSchemeV2.getSchemeType())) {
                        stuSchemeV2.setSchemeType(schemeType);
                    }
                    if (Objects.isNull(stuSchemeV2.getProgrammeId())) {
                        stuSchemeV2.setProgrammeId(programmeid);
                    }
                    if (Objects.isNull(stuSchemeV2.getNum())) {
                        stuSchemeV2.setNum(programmeid);
                    }
                    if(!StringUtils.hasText(stuSchemeV2.getProgrammeName())){
                        String majorType = "物理";
                        if (stuSchemeV2.getMajorType() == 2 || stuSchemeV2.getMajorType() == 4) {
                            majorType = "历史";
                        }
                        String name = majorType + stuSchemeV2.getBatch() + programmeid;
                        stuSchemeV2.setProgrammeName(name);
                    }

                    stuSchemeV2.setId(null);
                    stuSchemeV2.setSchemeName(sort + "");
                    if (StringUtils.hasText(stuSchemeV2.getRecruitType()) && !defaultRecruitType.contains(stuSchemeV2.getRecruitType())) {
                        defaultRecruitType.add(stuSchemeV2.getRecruitType());
                    }
                    sort++;
                }
                stuSchemes.forEach(stuSchemeV2 -> {
                    stuSchemeV2.setSchemeRecruitType(String.join(",", defaultRecruitType));
                    //判断专业是否有值
                    if (StringUtils.hasText(stuSchemeV2.getMajorList())) {
                        JSONArray majorList = JSONObject.parseArray(stuSchemeV2.getMajorList());
                        //先排序
                        majorList.sort((o1, o2) -> {
                            JSONObject jo1 = (JSONObject) o1;
                            JSONObject jo2 = (JSONObject) o2;
                            String sort1 = jo1.getString("sort");
                            String sort2 = jo2.getString("sort");
                            return sort1.compareTo(sort2);
                        });

                        for (int index = 0; index < majorList.size(); index++) {
                            JSONObject major = majorList.getJSONObject(index);
                            int majorSort = index + 1;
                            major.put("sort", "专业" + majorSort);
                            majorList.set(index, major);
                        }
                        stuSchemeV2.setMajorList(JSONObject.toJSONString(majorList));
                    }
                });
                boolean b = stuSchemeService.saveOrUpdateBatch(stuSchemes);
                HashMap<String, Object> object = new HashMap<>();
                object.put("bol", b);
                object.put("list", stuSchemes);

                //更新序号
                UpdateSort(stuSchemes.get(0));

                return R.ok(object);
            } else {
                return R.error("保存失败！");
            }
        }


//        for (StuScheme scheme : stuScheme) {
//            System.out.println("========id" + scheme.getProgrammeId());
//            if (scheme.getProgrammeId() == null) {
//                Integer maxProgrammeId = stuSchemeService.getObj(new QueryWrapper<StuScheme>()
//                        .select("ifnull(max(programme_id),0) as maxNum")
//                        .eq("stu_id", stuScheme[0].getStuId())
//                        .orderByDesc("programme_id"), i -> Integer.valueOf(i.toString())
//                );
//                List<StuScheme> schemes=stuSchemeService.list(new LambdaQueryWrapper<StuScheme>()
//                        .eq(scheme.getStuId()!=null,StuScheme::getStuId,scheme.getStuId())
//                        .orderByDesc(StuScheme::getNum).last("limit 1")
//                );
//                List<StuScheme> stuSchemes = Arrays.asList(stuScheme);
//                stuSchemes.forEach(i->{
//                    i.setProgrammeId(maxProgrammeId + 1);
//                    if(schemes.size()>0){
//                        i.setNum(schemes.get(0).getNum()+1);
//                    }else {
//                        i.setNum(1);
//                    }
//                });
//                long count = stuSchemeService.count(new LambdaQueryWrapper<StuScheme>().
//                        eq(StuScheme::getProgrammeName, scheme.getProgrammeName())
//                        .eq(StuScheme::getStuId, scheme.getStuId())
//                );
//                System.out.println("他的数量" + count);
//                if (count > 0) {
//                    return R.error("该方案名称已存在！");
//                } else {
//                    boolean b = stuSchemeService.saveBatch(stuSchemes);
//                    HashMap<String, Object> object = new HashMap<>();
//                    object.put("bol", b);
//                    object.put("list", stuSchemes);
//                    return R.ok(object);
//                }
//            } else {
////                stuSchemeService.remove(new LambdaQueryWrapper<StuScheme>()
////                        .eq(scheme.getProgrammeId() != null, StuScheme::getProgrammeId, scheme.getProgrammeId()));
//                List<StuScheme> stuSchemes = Arrays.asList(stuScheme);
//                System.out.println("stuSchemes" + stuSchemes);
//                boolean b = stuSchemeService.saveOrUpdateBatch(stuSchemes);
//                HashMap<String, Object> object = new HashMap<>();
//                object.put("bol", b);
//                object.put("list", stuSchemes);
//                return R.ok(object);
//            }
//        }
        return R.ok();
    }

    /**
     * 获取方案类型
     *
     * @param stuSchemes
     * @return
     */
    private Integer getSchemeType(List<StuSchemeV2> stuSchemes) {
        if (Objects.isNull(stuSchemes) || stuSchemes.size() == 0 || Objects.isNull(stuSchemes.get(0).getId())) {
            return 1;
        }
        List<StuSchemeV2> queryList = stuSchemeService.list(new QueryWrapper<StuSchemeV2>()
                .eq("stu_id", stuSchemes.get(0).getStuId())
                .eq("batch", stuSchemes.get(0).getBatch())
                .eq("major_type", stuSchemes.get(0).getMajorType())
                .eq("programme_id", stuSchemes.get(0).getProgrammeId())
        );

        if (Objects.isNull(queryList) || queryList.size() == 0 || queryList.size() != stuSchemes.size()) {
            return 1;
        }

        for (StuSchemeV2 stuScheme : stuSchemes) {
            Optional<StuSchemeV2> dataOptional = queryList.stream()
                    .filter(data -> data.getId().equals(stuScheme.getId()))
                    .findFirst();

            if (dataOptional.isPresent()) {
                if(StringUtils.hasText(dataOptional.get().getMajorList()) && StringUtils.hasText(stuScheme.getMajorList())){
                    List<JSONObject> oldMajorList = JSONArray.parseArray(dataOptional.get().getMajorList(), JSONObject.class);
                    List<JSONObject> majorList = JSONArray.parseArray(stuScheme.getMajorList(), JSONObject.class);

                    if(oldMajorList.size() != majorList.size()){
                        return 1;
                    }
                }
            } else {
                return 1;
            }
        }
        return queryList.get(0).getSchemeType();
    }

    @PostMapping("/getPrintScheme")
    public R getPrintScheme(String stuId) {

        List<Object> scheme = new ArrayList<Object>();
        List<StuSchemeV2> list = stuSchemeService.getProgrammes(stuId);

        String[] regulation = {"本科提前批单设", "本科提前批平行", "高职专科批提前", "本科普通批单设", "本科普通批平行", "高职专科批普通"};
        final List<String> regulationOrder = Arrays.asList(regulation);
        Collections.sort(list, new Comparator<StuSchemeV2>() {
            @Override
            public int compare(StuSchemeV2 o1, StuSchemeV2 o2) {
                String websiteName1 = (String) o1.getBatch();
                String websiteName2 = (String) o2.getBatch();
                int io1 = regulationOrder.indexOf(websiteName1);
                int io2 = regulationOrder.indexOf(websiteName2);
                return (io1 == -1 || io2 == -1) ? (io2 - io1) : (io1 - io2);
            }
        });
        List<Integer> codeList = new ArrayList<Integer>();
        List<String> batchList = new ArrayList<String>();
        if (list.size() > 0) {
            list.forEach(i -> codeList.add(i.getProgrammeId()));
            list.forEach(i -> batchList.add(i.getBatch()));
        }
        System.out.println("这个是集合" + list);
        for (int i = 0; i < codeList.size(); i++) {
            List<StuSchemeV2> lists = stuSchemeService.list(new LambdaQueryWrapper<StuSchemeV2>()
                    .eq(!StringUtil.isEmpty(stuId), StuSchemeV2::getStuId, stuId)
                    .eq(codeList.get(i) != null, StuSchemeV2::getProgrammeId, codeList.get(i))
                    .eq(batchList.get(i) != null, StuSchemeV2::getBatch, batchList.get(i))
            );
            fillSchemeMsg(list);

//            //按照序列名称排序
//            Collections.sort(lists, new Comparator<StuScheme>() {
//                @Override
//                public int compare(StuScheme scheme1, StuScheme scheme2) {
//                    if(ObjectUtils.isEmpty(scheme1.getSchemeName()) || ObjectUtils.isEmpty(scheme2.getSchemeName())){
//                        return 1;
//                    }
//                    if("备选".equals(scheme1.getSchemeName())){
//                        return 1;
//                    }
//                    return scheme1.getSchemeName().compareTo(scheme2.getSchemeName());
//                }
//            });

            scheme.add(i, lists);
        }

        return R.ok(scheme);
    }

    @GetMapping("/getPrintSchemePdf")
    public void getPrintSchemePdf(String stuId, HttpServletResponse response) {
        List<List<StuSchemeV2>> scheme = new ArrayList<>();
        List<StuSchemeV2> list = stuSchemeService.getProgrammes(stuId);

        String[] regulation = {"本科提前批单设", "本科提前批平行", "高职专科批提前", "本科普通批单设", "本科普通批平行", "高职专科批普通"};
        final List<String> regulationOrder = Arrays.asList(regulation);
        Collections.sort(list, new Comparator<StuSchemeV2>() {
            @Override
            public int compare(StuSchemeV2 o1, StuSchemeV2 o2) {
                String websiteName1 = (String) o1.getBatch();
                String websiteName2 = (String) o2.getBatch();
                int io1 = regulationOrder.indexOf(websiteName1);
                int io2 = regulationOrder.indexOf(websiteName2);
                return (io1 == -1 || io2 == -1) ? (io2 - io1) : (io1 - io2);
            }
        });
        List<Integer> codeList = new ArrayList<Integer>();
        List<String> batchList = new ArrayList<String>();
        if (list.size() > 0) {
            list.forEach(i -> codeList.add(i.getProgrammeId()));
            list.forEach(i -> batchList.add(i.getBatch()));
        }
        System.out.println("这个是集合" + list);
        for (int i = 0; i < codeList.size(); i++) {
            List<StuSchemeV2> lists = stuSchemeService.list(new LambdaQueryWrapper<StuSchemeV2>()
                    .eq(!StringUtil.isEmpty(stuId), StuSchemeV2::getStuId, stuId)
                    .eq(codeList.get(i) != null, StuSchemeV2::getProgrammeId, codeList.get(i))
                    .eq(batchList.get(i) != null, StuSchemeV2::getBatch, batchList.get(i))
            );
            fillSchemeMsg(list);
            //按照序列名称排序
//            Collections.sort(lists, new Comparator<StuScheme>() {
//                @Override
//                public int compare(StuScheme scheme1, StuScheme scheme2) {
//                    if(ObjectUtils.isEmpty(scheme1.getSchemeName()) || ObjectUtils.isEmpty(scheme2.getSchemeName())){
//                        return 1;
//                    }
//                    if("备选".equals(scheme1.getSchemeName())){
//                        return 1;
//                    }
//                    return scheme1.getSchemeName().compareTo(scheme2.getSchemeName());
//                }
//            });
            scheme.add(i, lists);
        }

        Student student = studentService.getById(stuId);
        String filePath = myprops.getSavePath() + File.separator + DateUtils.format(new Date(), "yyyyMMdd");
        log.info("保存文件地址:{}", filePath);
        File folder = new File(filePath);
        if (!folder.exists()) {
            folder.mkdirs();
            log.info("创建文件夹{}成功", filePath);
        }
        String fileName = student.getName() + "高考志愿方案.pdf";
        PdfUtil.createPdfV2(filePath + File.separator + fileName, scheme, student, false);

        String downloadFileName = new String(fileName.getBytes(StandardCharsets.UTF_8), StandardCharsets.ISO_8859_1);

        response.reset();
        response.setCharacterEncoding("UTF-8");
        response.setContentType("multipart/form-data");
        response.addHeader("Content-Disposition", "attachment; filename=\"" + downloadFileName + "\"");

        InputStream input = null;
        OutputStream output = null;
        try {
            File file = new File(filePath + File.separator + fileName);
            input = new FileInputStream(file);
            output = response.getOutputStream();
            byte[] buff = new byte[1024];
            int index;
            while ((index = input.read(buff)) != -1) {
                output.write(buff, 0, index);
                output.flush();
            }
        } catch (Exception e) {
            log.error("download template error", e);
        } finally {
            if (input != null) {
                try {
                    input.close();
                } catch (IOException e) {
                    log.error("关闭input异常：", e);
                }
            }
            if (output != null) {
                try {
                    output.close();
                } catch (IOException e) {
                    log.error("关闭output异常：", e);
                }
            }
        }
    }

    //调整排序
    @PostMapping("UpdateSort")
    public R UpdateSort(@RequestBody StuSchemeV2 stuSchemeReq) {
        //查询学生方案信息
        List<StuSchemeV2> list = stuSchemeService.getProgrammes(stuSchemeReq.getStuId());

        String[] regulation = {"本科提前批单设", "本科提前批平行", "高职专科批提前", "本科普通批单设", "本科普通批平行", "高职专科批普通"};
        final List<String> regulationOrder = Arrays.asList(regulation);

        //按照batch分组
        Map<String, List<StuSchemeV2>> groupByBatch =
                list.stream().collect(Collectors.groupingBy(StuSchemeV2::getBatch));

        int num = 1;
        for (String batchName : regulationOrder) {
            if (!ObjectUtils.isEmpty(groupByBatch.get(batchName))) {
                //按照选科在分组
                Map<Integer, List<StuSchemeV2>> groupByMajorType = groupByBatch.get(batchName).stream().collect(Collectors.groupingBy(StuSchemeV2::getMajorType));
                if(!ObjectUtils.isEmpty(groupByMajorType.get(1))){
                    int programmeId = 1;
                    for (StuSchemeV2 stuScheme : groupByMajorType.get(1)) {
                        StuSchemeV2 updateStuScheme = new StuSchemeV2();
                        String majorType = "物理";
                        if (stuScheme.getMajorType() == 2) {
                            majorType = "历史";
                        }
                        String name = majorType + stuScheme.getBatch() + (programmeId);
                        updateStuScheme.setProgrammeName(name);
                        updateStuScheme.setProgrammeId(programmeId);
                        updateStuScheme.setNum(num);
                        LambdaQueryWrapper wrapper = new LambdaQueryWrapper<StuScheme>()
                                .eq(StuScheme::getStuId, stuScheme.getStuId())
                                .eq(StuScheme::getProgrammeId, stuScheme.getProgrammeId())
                                .eq(StuScheme::getMajorType, stuScheme.getMajorType())
                                .eq(StuScheme::getBatch, stuScheme.getBatch());
                        stuSchemeService.update(updateStuScheme, wrapper);
                        programmeId++;
                        num++;
                    }
                }

                if(!ObjectUtils.isEmpty(groupByMajorType.get(2))){
                    int programmeId = 1;
                    for (StuSchemeV2 stuScheme : groupByMajorType.get(2)) {
                        StuSchemeV2 updateStuScheme = new StuSchemeV2();
                        String majorType = "物理";
                        if (stuScheme.getMajorType() == 2) {
                            majorType = "历史";
                        }
                        String name = majorType + stuScheme.getBatch() + (programmeId);
                        updateStuScheme.setProgrammeName(name);
                        updateStuScheme.setProgrammeId(programmeId);
                        updateStuScheme.setNum(num);
                        LambdaQueryWrapper wrapper = new LambdaQueryWrapper<StuScheme>()
                                .eq(StuScheme::getStuId, stuScheme.getStuId())
                                .eq(StuScheme::getProgrammeId, stuScheme.getProgrammeId())
                                .eq(StuScheme::getMajorType, stuScheme.getMajorType())
                                .eq(StuScheme::getBatch, stuScheme.getBatch());
                        stuSchemeService.update(updateStuScheme, wrapper);
                        programmeId++;
                        num++;
                    }
                }

            }
        }

        return R.ok();
    }

    /**
     * 智慧生成
     *
     * @param autoCreate
     * @return
     */
    @PostMapping("/autoCreate")
    public R autoCreate(@RequestBody AutoCreateVo autoCreate) {
        //先判断学生是否填充分数位次
        if (Objects.isNull(autoCreate.getPrecedence()) || autoCreate.getPrecedence() <= 0) {
            return R.error("请输入分数位次");
        }
        if (Objects.isNull(autoCreate.getChongNum()) || Objects.isNull(autoCreate.getWenNum()) || Objects.isNull(autoCreate.getBaoNum())) {
            return R.error("请输入冲稳报个数");
        }
        if (autoCreate.getChongNum() <= 0 || autoCreate.getWenNum() <= 0 || autoCreate.getBaoNum() <= 0) {
            return R.error("请输入冲稳报个数");
        }
        if (Objects.isNull(autoCreate.getStuId())) {
            return R.error("参数不合法，缺少stuId");
        }
        Student student = studentService.getById(autoCreate.getStuId());
        if (Objects.isNull(student)) {
            return R.error("未查询到该学生信息");
        }
        Integer precedence = autoCreate.getPrecedence();

        //查询符合条件的学校信息
        LambdaQueryWrapper<SchoolV2> query = new LambdaQueryWrapper<SchoolV2>()
                .eq(SchoolV2::getBatch, autoCreate.getBatch())
                .eq(SchoolV2::getType, student.getMajor())
                .in(!ObjectUtils.isEmpty(autoCreate.getRecruitType()), SchoolV2::getRecruitType, autoCreate.getRecruitType());

        List<String> subject = new ArrayList<>();
        subject.add(student.getSubject1());
        subject.add(student.getSubject2());
        subject.add(student.getSubject1()+","+student.getSubject2());
        subject.add("不限");
        query.in(SchoolV2::getSubject, subject);

        List<String> codeList = new ArrayList<>();
        //办学性质||院校层级||博硕资格不为空||城市不为空
        if (!ObjectUtils.isEmpty(autoCreate.getNature()) || !ObjectUtils.isEmpty(autoCreate.getHierarchys()) || !ObjectUtils.isEmpty(autoCreate.getQualifications()) || !ObjectUtils.isEmpty(autoCreate.getCity())) {
            List<String> labelCode = new ArrayList<>();
            if (!ObjectUtils.isEmpty(autoCreate.getHierarchys()) || !ObjectUtils.isEmpty(autoCreate.getQualifications())) {
                List<SchoolLabel> labelList = schoolLabelService.getByParam(String.join("|", autoCreate.getHierarchys()), String.join("|", autoCreate.getQualifications()));
                labelList.forEach(i -> labelCode.add(i.getNewCode()));
            }

            LambdaQueryWrapper<SchoolLabel> schoolLabelQuery = new LambdaQueryWrapper<SchoolLabel>();
            if (labelCode.size() > 0) {
                schoolLabelQuery.in(SchoolLabel::getCode, labelCode);
            }
            if (Objects.nonNull(autoCreate.getCity()) && autoCreate.getCity().size() > 0) {
                schoolLabelQuery.in(SchoolLabel::getCity, autoCreate.getCity());
            }
            if (Objects.nonNull(autoCreate.getNature()) && autoCreate.getNature().size() > 0) {
                schoolLabelQuery.in(SchoolLabel::getNature, autoCreate.getNature());
            }
            schoolLabelQuery.select(SchoolLabel::getNewCode);
            List<SchoolLabel> schoolLabels = schoolLabelService.list(schoolLabelQuery);
            codeList = schoolLabels.stream().map(SchoolLabel::getNewCode).collect(Collectors.toList());
        }
        if (!StringUtil.isEmpty(autoCreate.getType()) && !autoCreate.getType().equals("[其他]")) {
            query.in(!StringUtil.isEmpty(autoCreate.getType()), SchoolV2::getSchoolType, autoCreate.getType());
        }
        if (Objects.nonNull(codeList) && codeList.size() > 0) {
            query.in(SchoolV2::getCode, codeList);
        }
        if (!CollectionUtils.isEmpty(autoCreate.getMajors())) {
            List<Long> majorSchoolIdList = majorService.selectMajorSchoolId(student.getMajor(), autoCreate.getBatch(), autoCreate.getMajors());
            if (!CollectionUtils.isEmpty(majorSchoolIdList)) {
                query.in(SchoolV2::getId, majorSchoolIdList);
            }
        }
        query.orderByAsc(SchoolV2::getGroupProposedwc);
        List<SchoolV2> result = schoolService.list(query);

        for (SchoolV2 schoolV2 : result) {
            getSchoolProbability(schoolV2, precedence);
        }
        List<StuSchemeV2> stuSchemeV2List = new ArrayList<>();
        //获取冲稳保的学校
        List<SchoolV2> chongSchool = result.stream().filter(schoolV2 -> "冲".equals(schoolV2.getProbabilityName())).collect(Collectors.toList());
        List<SchoolV2> wenSchool = result.stream().filter(schoolV2 -> "稳".equals(schoolV2.getProbabilityName())).collect(Collectors.toList());
        List<SchoolV2> baoSchool = result.stream().filter(schoolV2 -> "保".equals(schoolV2.getProbabilityName())).collect(Collectors.toList());

        //在基准位次基础上（录取概率50%）向上到录取概率第一个1%学校的位次，按照位次区间进行平均抽取冲的院校，如抽取数量不满足条件要求，在向上抽取
        List<SchoolV2> firstChongSchool = chongSchool.stream().filter(schoolV2 -> schoolV2.getProbabilityNum().compareTo(BigDecimal.valueOf(1)) > 0 && schoolV2.getProbabilityNum().compareTo(BigDecimal.valueOf(50)) <= 0).collect(Collectors.toList());
        //在基准位次基础上（录取概率50%）向下到录取概率79%，按照位次平均抽取
        List<SchoolV2> firstWenSchool = wenSchool.stream().filter(schoolV2 -> schoolV2.getProbabilityNum().compareTo(BigDecimal.valueOf(50)) > 0 && schoolV2.getProbabilityNum().compareTo(BigDecimal.valueOf(79)) <= 0).collect(Collectors.toList());
        //从录取率80%-99%中，按照位次平均抽取院校
        List<SchoolV2> firstBaoSchool = baoSchool.stream().filter(schoolV2 -> schoolV2.getProbabilityNum().compareTo(BigDecimal.valueOf(79)) > 0 && schoolV2.getProbabilityNum().compareTo(BigDecimal.valueOf(98)) <= 0).collect(Collectors.toList());

        //获取冲稳保意向院校
        List<SchoolV2> likeChongSchool = new ArrayList<>();
        List<SchoolV2> likeWenSchool = new ArrayList<>();
        List<SchoolV2> likeBaoSchool = new ArrayList<>();
        if (!CollectionUtils.isEmpty(autoCreate.getSchools())) {
            likeChongSchool = chongSchool.stream().filter(schoolV2 -> autoCreate.getSchools().contains(schoolV2.getSchoolName())).collect(Collectors.toList());
            likeWenSchool = wenSchool.stream().filter(schoolV2 -> autoCreate.getSchools().contains(schoolV2.getSchoolName())).collect(Collectors.toList());
            likeBaoSchool = baoSchool.stream().filter(schoolV2 -> autoCreate.getSchools().contains(schoolV2.getSchoolName())).collect(Collectors.toList());
        }

        if (autoCreate.getChongNum() > chongSchool.size()) {
            autoCreate.setChongNum(chongSchool.size());
        }
        if (autoCreate.getWenNum() > wenSchool.size()) {
            autoCreate.setWenNum(wenSchool.size());
        }
        if (autoCreate.getBaoNum() > baoSchool.size()) {
            autoCreate.setBaoNum(baoSchool.size());
        }
        Integer schemeNum = 1;
        Integer chongLike = likeChongSchool.size();
        Integer wenLike = likeWenSchool.size();
        Integer baoLike = likeBaoSchool.size();

        if(Objects.nonNull(firstChongSchool) && firstChongSchool.size()>0){
            chongSchool.removeAll(firstChongSchool);
        }
        //冲的学校倒序排列
        if(Objects.nonNull(chongSchool) && chongSchool.size()>0){
            Collections.reverse(chongSchool);
        }

        //冲学校和专业
        for (int i = 0; i < autoCreate.getChongNum(); i++) {
            // 意向院校标识
            Boolean likeFlag = false;
            if (i < chongLike) {
                likeFlag = true;
            }

            SchoolV2 schoolV2 = getSchoolMsg(likeChongSchool, firstChongSchool, chongSchool, stuSchemeV2List, likeFlag);

            if (Objects.isNull(schoolV2)) {
                continue;
            }
            StuSchemeV2 stuSchemeV2 = getAutoScheme(autoCreate, student, schoolV2);
            stuSchemeV2.setNum(schemeNum);
            stuSchemeV2.setSchemeNum(schemeNum);
            stuSchemeV2.setSubject1(student.getSubject1());
            stuSchemeV2.setSubject2(student.getSubject2());
            //获取学校专业
            List<JSONObject> majorList = getMajorMsg(schoolV2, stuSchemeV2, precedence, autoCreate);
            stuSchemeV2.setMajorList(JSONObject.toJSONString(majorList));

            schemeNum++;
            stuSchemeV2List.add(stuSchemeV2);
        }

        if(Objects.nonNull(firstWenSchool) && firstWenSchool.size()>0){
            wenSchool.removeAll(firstWenSchool);
        }

        //稳学校和专业
        for (int i = 0; i < autoCreate.getWenNum(); i++) {
            // 意向院校标识
            Boolean likeFlag = false;
            if (i < wenLike) {
                likeFlag = true;
            }

            SchoolV2 schoolV2 = getSchoolMsg(likeWenSchool, firstWenSchool, wenSchool, stuSchemeV2List, likeFlag);

            if (Objects.isNull(schoolV2)) {
                continue;
            }
            StuSchemeV2 stuSchemeV2 = getAutoScheme(autoCreate, student, schoolV2);
            stuSchemeV2.setNum(schemeNum);
            stuSchemeV2.setSchemeNum(schemeNum);
            stuSchemeV2.setSubject1(student.getSubject1());
            stuSchemeV2.setSubject2(student.getSubject2());
            //获取学校专业
            List<JSONObject> majorList = getMajorMsg(schoolV2, stuSchemeV2, precedence, autoCreate);
            stuSchemeV2.setMajorList(JSONObject.toJSONString(majorList));

            schemeNum++;
            stuSchemeV2List.add(stuSchemeV2);
        }

        if(Objects.nonNull(firstBaoSchool) && firstBaoSchool.size()>0){
            baoSchool.removeAll(firstBaoSchool);
        }

        //保学校和专业
        for (int i = 0; i < autoCreate.getBaoNum(); i++) {
            Boolean likeFlag = false;
            if (i < baoLike) {
                likeFlag = true;
            }

            SchoolV2 schoolV2 = getSchoolMsg(likeBaoSchool, firstBaoSchool, baoSchool, stuSchemeV2List, likeFlag);

            if (Objects.isNull(schoolV2)) {
                continue;
            }
            StuSchemeV2 stuSchemeV2 = getAutoScheme(autoCreate, student, schoolV2);
            stuSchemeV2.setNum(schemeNum);
            stuSchemeV2.setSchemeNum(schemeNum);
            stuSchemeV2.setSubject1(student.getSubject1());
            stuSchemeV2.setSubject2(student.getSubject2());
            //获取学校专业
            List<JSONObject> majorList = getMajorMsg(schoolV2, stuSchemeV2, precedence, autoCreate);
            stuSchemeV2.setMajorList(JSONObject.toJSONString(majorList));

            schemeNum++;
            stuSchemeV2List.add(stuSchemeV2);
        }

        //按照录取概率排序
        stuSchemeV2List = stuSchemeV2List.stream().sorted(Comparator.comparing(StuSchemeV2::getGroupProposedwc))
                .collect(Collectors.toList());

        //修改序号
        for (int i = 0; i < stuSchemeV2List.size(); i++) {
            stuSchemeV2List.get(i).setSchemeNum(i + 1);
            stuSchemeV2List.get(i).setNum(i + 1);
            if (Objects.nonNull(autoCreate.getProgrammeId()) && autoCreate.getProgrammeId() > 0) {
                stuSchemeV2List.get(i).setProgrammeId(autoCreate.getProgrammeId());
            }
        }
        if(stuSchemeV2List.size() == 0){
            return R.error("暂未查询到到符合要求的方案信息");
        }
        R saveR = saveScheme(stuSchemeV2List.toArray(new StuSchemeV2[stuSchemeV2List.size()]));
        log.info("保存返回={}", saveR);
        R returnR = R.ok();
        if (!CollectionUtils.isEmpty(stuSchemeV2List)) {
            returnR.put("programmeId", stuSchemeV2List.get(0).getProgrammeId());
        }
        returnR.put("batch", autoCreate.getBatch());
        returnR.put("stuId", autoCreate.getStuId());
        returnR.put("list", stuSchemeV2List);
        return returnR;
    }

    /**
     * 获取智能推荐院校
     *
     * @param likeSchool      意向院校
     * @param firstSchool     首选院校
     * @param allSchool       所有院校
     * @param stuSchemeV2List 方案列表
     * @param likeFlag        意向院校标识
     * @return
     */
    private SchoolV2 getSchoolMsg(List<SchoolV2> likeSchool, List<SchoolV2> firstSchool, List<SchoolV2> allSchool, List<StuSchemeV2> stuSchemeV2List, Boolean likeFlag) {
        SchoolV2 schoolV2 = null;
        //意向院校排在第一个
        if (!CollectionUtils.isEmpty(likeSchool) && likeFlag) {
            schoolV2 = getRandomElement(likeSchool);
            likeSchool.remove(schoolV2);
        } else {
            schoolV2 = getRandomElement(firstSchool);
            if (Objects.isNull(schoolV2)) {
                schoolV2 = getAllSchool(allSchool);
            }
            firstSchool.remove(schoolV2);
            allSchool.remove(schoolV2);
        }

        return schoolV2;
    }

    /**
     * 获取智能生成的院校方案信息
     *
     * @param autoCreate
     * @param student
     * @param schoolV2
     * @return
     */
    private StuSchemeV2 getAutoScheme(AutoCreateVo autoCreate, Student student, SchoolV2 schoolV2) {
        StuSchemeV2 stuSchemeV2 = new StuSchemeV2();
        stuSchemeV2.setStuId(autoCreate.getStuId() + "");
        stuSchemeV2.setSchoolCode(schoolV2.getCode());
        stuSchemeV2.setSchoolName(schoolV2.getSchoolName());
        stuSchemeV2.setGroupCode(schoolV2.getGroupCode());
        stuSchemeV2.setBatch(schoolV2.getBatch());
        stuSchemeV2.setRecruitType(schoolV2.getRecruitType());
        stuSchemeV2.setPlan2022(schoolV2.getPlan2022());
        stuSchemeV2.setMajorPlan(schoolV2.getMajorPlan());
        stuSchemeV2.setMajorType(student.getMajor());
        stuSchemeV2.setScore(autoCreate.getScore());
        stuSchemeV2.setPrecedence(autoCreate.getPrecedence());
        stuSchemeV2.setMajorType(student.getMajor());
        stuSchemeV2.setGroupProposedwc(schoolV2.getGroupProposedwc());
        stuSchemeV2.setSchemeType(2);

        return stuSchemeV2;
    }

    /**
     * 获取智能生成专业信息
     *
     * @param stuSchemeV2
     * @return
     */
    private List<JSONObject> getMajorMsg(SchoolV2 schoolV2, StuSchemeV2 stuSchemeV2, Integer precedence, AutoCreateVo autoCreate) {
        List<MajorV2> allMajors = majorService.list(new LambdaQueryWrapper<MajorV2>()
                .eq(MajorV2::getCode, stuSchemeV2.getSchoolCode())
                .eq(MajorV2::getType, stuSchemeV2.getMajorType())
                .eq(MajorV2::getGroupCode, stuSchemeV2.getGroupCode())
                .eq(MajorV2::getBatch, stuSchemeV2.getBatch())
                .orderByDesc(MajorV2::getMajorWeici)
        );
        List<String> scoreFirst = Arrays.asList("分数优先", "一志愿录取");
        List<String> majorFirst = Arrays.asList("专业清", "一专再分", "分数级差");


        List<MajorV2> likeMajors = new ArrayList<>();
        //录取位次最低的两个专业
        List<MajorV2> lastTowMajors = new ArrayList<>();

        allMajors.forEach(majorV2 -> {
            getMajorProbability(majorV2, precedence);
            //优先获取意向专业
            if (!CollectionUtils.isEmpty(autoCreate.getMajors())) {
                for (String likeName : autoCreate.getMajors()) {
                    if (majorV2.getMajorName().contains(likeName)) {
                        likeMajors.add(majorV2);
                    } else if (StringUtils.hasText(majorV2.getMajorDesc()) && majorV2.getMajorDesc().contains(likeName)) {
                        likeMajors.add(majorV2);
                    }
                }
            }
        });

        Integer likeSize = likeMajors.size();

        List<JSONObject> majorList = new ArrayList<>();
        Integer maxMajorNum = 6;
        if (allMajors.size() < maxMajorNum) {
            maxMajorNum = allMajors.size();
        }
        //如果是"专业清", "一专再分", "分数级差"
        if (StringUtils.hasText(schoolV2.getMajorPlan()) && (majorFirst.contains(schoolV2.getMajorPlan()) || schoolV2.getMajorPlan().startsWith("级差"))) {
            if (Objects.nonNull(likeMajors) && likeMajors.size() > 0) {
                allMajors.removeAll(likeMajors);
            }
            //直接从录取概率为60%到第一个99%处按照检索条件抽取6个专业
            List<MajorV2> first = allMajors.stream().filter(majorV2 -> majorV2.getProbabilityNum().compareTo(new BigDecimal("60")) > 0 && majorV2.getProbabilityNum().compareTo(new BigDecimal("99.01")) < 0).collect(Collectors.toList());
            //如果数目不够，在99%以后向下依次选取；
            List<MajorV2> second = allMajors.stream().filter(majorV2 -> majorV2.getProbabilityNum().compareTo(new BigDecimal("99.01")) >= 0).collect(Collectors.toList());
            //如果还不够，从60%处向前依次选取，
            List<MajorV2> third = allMajors.stream().filter(majorV2 -> majorV2.getProbabilityNum().compareTo(new BigDecimal("60")) <= 0).collect(Collectors.toList());

            List<MajorV2> fanganMajor = new ArrayList<>();
            fanganMajor.addAll(first);
            fanganMajor.addAll(second);
            fanganMajor.addAll(third);
            for (int majorSort = 1; majorSort <= maxMajorNum; majorSort++) {
                MajorV2 majorV2 = null;
                if (!CollectionUtils.isEmpty(likeMajors)) {
                    majorV2 = getRandomElement(likeMajors);
                    if (Objects.nonNull(majorV2)) {
                        likeMajors.remove(majorV2);
                    }
                } else if(fanganMajor.size()>0){
                    majorV2 = fanganMajor.get(0);
                    //判断本次获取的专业是否存在
                    if (Objects.nonNull(majorV2)) {
                        fanganMajor.remove(majorV2);
                    }
                }
                if (Objects.isNull(majorV2)) {
                    continue;
                }
                majorList.add(covertMajorMsg(majorSort, majorV2));
            }
        } else {
            if (Objects.nonNull(likeMajors) && likeMajors.size() > 0) {
                allMajors.removeAll(likeMajors);
            }

            if (Objects.nonNull(allMajors) && allMajors.size() >= 2) {
                lastTowMajors.add(allMajors.get(0));
                lastTowMajors.add(allMajors.get(1));
                allMajors.removeAll(lastTowMajors);
            }

            //获取冲稳保的专业
            List<MajorV2> chongMajor = allMajors.stream().filter(majorV2 -> "冲".equals(majorV2.getProbabilityName())).collect(Collectors.toList());
            List<MajorV2> wenMajor = allMajors.stream().filter(majorV2 -> "稳".equals(majorV2.getProbabilityName())).collect(Collectors.toList());
            List<MajorV2> baoMajor = allMajors.stream().filter(majorV2 -> "保".equals(majorV2.getProbabilityName())).collect(Collectors.toList());

            for (int majorSort = 1; majorSort <= maxMajorNum; majorSort++) {
                MajorV2 majorV2 = null;
                if (!CollectionUtils.isEmpty(likeMajors)) {
                    majorV2 = getRandomElement(likeMajors);
                    if (Objects.nonNull(majorV2)) {
                        likeMajors.remove(majorV2);
                    }
                } else {
                    //最后两个专业选择本学校中录取位次最低的两个专业
                    if (majorSort > maxMajorNum - 2 && lastTowMajors.size() > 0) {
                        majorV2 = getRandomElement(lastTowMajors);
                        //判断本次获取的专业是否存在
                        if (Objects.nonNull(majorV2)) {
                            lastTowMajors.remove(majorV2);
                        }
                    } else {
                        majorV2 = getRandomElement(allMajors);
                        //判断本次获取的专业是否存在
                        if (Objects.nonNull(majorV2)) {
                            allMajors.remove(majorV2);
                        }
                    }
                }
                if (Objects.isNull(majorV2)) {
                    continue;
                }

                majorList.add(covertMajorMsg(majorSort, majorV2));
            }
            //无意向专业要求，专业按照录取概率由低到高
            if (likeSize == 0 && Objects.nonNull(majorList) && majorList.size() > 1) {
                Collections.sort(majorList, (major1, major2) -> major1.getInteger("majorWeici") - major2.getInteger("majorWeici"));
                for (int index = 0; index < majorList.size(); index++) {
                    Integer majorSort = index + 1;
                    majorList.get(index).put("sort", "专业" + majorSort);
                }
            }
        }

        return majorList;
    }

    /**
     * 组装专业信息
     * @param majorSort
     * @param majorV2
     * @return
     */
    private JSONObject covertMajorMsg(int majorSort, MajorV2 majorV2) {
        JSONObject majorMsg = new JSONObject();
        majorMsg.put("sort", "专业" + majorSort);
        majorMsg.put("majorCode", majorV2.getMajorCode());
        majorMsg.put("majorName", majorV2.getMajorName());
        majorMsg.put("majorLimit", majorV2.getMajorLimit());
        majorMsg.put("majorDesc", majorV2.getMajorDesc());
        majorMsg.put("level", majorV2.getLevel());
        majorMsg.put("plan2017", majorV2.getPlan2017());
        majorMsg.put("msg2015", majorV2.getMsg2015());
        majorMsg.put("msg2016", majorV2.getMsg2016());
        majorMsg.put("msg2017", majorV2.getMsg2017());
        if (Objects.isNull(majorV2.getMajorWeici())) {
            majorMsg.put("majorWeici", 1);
        } else {
            majorMsg.put("majorWeici", majorV2.getMajorWeici());
        }
        return majorMsg;
    }

    /**
     * 随机获取list的对象
     *
     * @param list
     * @param <T>
     * @return
     */
    private <T> T getRandomElement(List<T> list) {
        if (list == null || list.size() == 0) {
            return null;
        }

        Random random = new Random();
        int index = random.nextInt(list.size());
        return list.get(index);
    }

    /**
     * 依次获取
     * @param allSchool
     * @return
     */
    private SchoolV2 getAllSchool(List<SchoolV2> allSchool) {
        if(Objects.nonNull(allSchool) && allSchool.size()>0){
            return allSchool.get(0);
        }
        return null;
    }

    /**
     * 方案打印辅助信息填充
     * @param list
     */
    private void fillSchemeMsg(List<StuSchemeV2> list) {
        for (StuSchemeV2 stuScheme : list) {
            if ("0".equals(stuScheme.getSchemeChange())) {
                stuScheme.setSchemeChangeFlag(true);
            } else {
                stuScheme.setSchemeChangeFlag(false);
            }
            SchoolV2 schoolV2 = schoolService.queryByParams(stuScheme.getMajorType(), stuScheme.getBatch(), stuScheme.getSchoolCode(), stuScheme.getGroupCode());
            if (Objects.nonNull(schoolV2)) {
                stuScheme.setShiftLine2021(schoolV2.getShiftLine2021());
                stuScheme.setRanking2021(schoolV2.getRanking2021());
                stuScheme.setGroupProposedwc(schoolV2.getGroupProposedwc());
                stuScheme.setGroupProposedScore(schoolV2.getGroupProposedScore());
            }
            //获取报考专业
            if (StringUtils.hasText(stuScheme.getMajorList())) {
                List<JSONObject> majorList = JSONArray.parseArray(stuScheme.getMajorList(), JSONObject.class);
                for (JSONObject major : majorList) {
                    MajorV2 major1 = majorV2Service.selectByParams(stuScheme.getSchoolCode(), stuScheme.getGroupCode(), major.getString("majorCode"));
                    if (Objects.nonNull(major1)) {
                        if (StringUtils.hasText(major1.getExamLimit())) {
                            major.put("examLimit", major1.getExamLimit());
                        } else {
                            major.put("examLimit", "");
                        }
                        if (StringUtils.hasText(major1.getMajorDesc())) {
                            major.put("majorDesc", major1.getMajorDesc());
                        } else {
                            major.put("majorDesc", "");
                        }
                        if (StringUtils.hasText(major1.getMsg2015())) {
                            major.put("msg2015", major1.getMsg2015());
                        } else {
                            major.put("msg2015", "");
                        }
                        if (StringUtils.hasText(major1.getToudang2015())) {
                            major.put("toudang2015", major1.getToudang2015());
                        } else {
                            major.put("toudang2015", "");
                        }
                        if (StringUtils.hasText(major1.getShiftLine2015())) {
                            major.put("shiftLine2015", major1.getShiftLine2015());
                        } else {
                            major.put("shiftLine2015", "");
                        }
                        if (StringUtils.hasText(major1.getRanking2015())) {
                            major.put("ranking2015", major1.getRanking2015());
                        } else {
                            major.put("ranking2015", "");
                        }
                        if (StringUtils.hasText(major1.getMinShiftLine2015())) {
                            major.put("minShiftLine2015", major1.getMinShiftLine2015());
                        } else {
                            major.put("minShiftLine2015", "");
                        }
                        if (StringUtils.hasText(major1.getMinRanking2015())) {
                            major.put("minRanking2015", major1.getMinRanking2015());
                        } else {
                            major.put("minRanking2015", "");
                        }
                        if (StringUtils.hasText(major1.getMsg2016())) {
                            major.put("msg2016", major1.getMsg2016());
                        } else {
                            major.put("msg2016", "");
                        }
                        if (StringUtils.hasText(major1.getToudang2016())) {
                            major.put("toudang2016", major1.getToudang2016());
                        } else {
                            major.put("toudang2016", "");
                        }
                        if (StringUtils.hasText(major1.getShiftLine2016())) {
                            major.put("shiftLine2016", major1.getShiftLine2016());
                        } else {
                            major.put("shiftLine2016", "");
                        }
                        if (StringUtils.hasText(major1.getRanking2016())) {
                            major.put("ranking2016", major1.getRanking2016());
                        } else {
                            major.put("ranking2016", "");
                        }
                        if (StringUtils.hasText(major1.getMinShiftLine2016())) {
                            major.put("minShiftLine2016", major1.getMinShiftLine2016());
                        } else {
                            major.put("minShiftLine2016", "");
                        }
                        if (StringUtils.hasText(major1.getMinRanking2016())) {
                            major.put("minRanking2016", major1.getMinRanking2016());
                        } else {
                            major.put("minRanking2016", "");
                        }
                        if (StringUtils.hasText(major1.getMsg2017())) {
                            major.put("msg2017", major1.getMsg2017());
                        } else {
                            major.put("msg2017", "");
                        }
                        if (StringUtils.hasText(major1.getToudang2017())) {
                            major.put("toudang2017", major1.getToudang2017());
                        } else {
                            major.put("toudang2017", "");
                        }
                        if (StringUtils.hasText(major1.getShiftLine2017())) {
                            major.put("shiftLine2017", major1.getShiftLine2017());
                        } else {
                            major.put("shiftLine2017", "");
                        }
                        if (StringUtils.hasText(major1.getRanking2017())) {
                            major.put("ranking2017", major1.getRanking2017());
                        } else {
                            major.put("ranking2017", "");
                        }
                        if (StringUtils.hasText(major1.getMinShiftLine2017())) {
                            major.put("minShiftLine2017", major1.getMinShiftLine2017());
                        } else {
                            major.put("minShiftLine2017", "");
                        }
                        if (StringUtils.hasText(major1.getMinRanking2017())) {
                            major.put("minRanking2017", major1.getMinRanking2017());
                        } else {
                            major.put("minRanking2017", "");
                        }
                        if (StringUtils.hasText(major1.getLevel())) {
                            major.put("level", major1.getLevel());
                        } else {
                            major.put("level", "");
                        }
                        major.put("plan2017", major1.getPlan2017());
                        major.put("probability", major1.getProbability());
                        major.put("probabilityName", major1.getProbability());
                    }
                }
                stuScheme.setMajorList(JSONObject.toJSONString(majorList));
            }
            if(StringUtils.hasText(stuScheme.getSubject())){
                stuScheme.setSubject(schoolV2.getSubject().replaceAll(",","+"));
            }
        }
    }
}
